﻿namespace CSP.Utils

module WorkQueue =

    open System.Collections.Generic
    open ListMap

    /// A mutable queue of work items.
    type internal WorkQueue<'k,'a> when 'k: comparison = { Open: List<'a>; Closed: ListMap<'k,'a> }

    /// Creates an empty queue.
    let internal create getKey (list: #seq<_>) = { Open = new List<_>(list); Closed = empty getKey }

    /// Gets the next open work item, returns it and closes it.
    let internal next queue =
        if queue.Open.Count = 0 then None
        else
            let x = queue.Open.[0]
            queue.Open.RemoveAt(0)
            add x queue.Closed
            Some x

    /// reopens all work items for a given key.
    let internal reopen key queue =
        let items = findAndRemove key queue.Closed
        queue.Open.AddRange(items)

